/*
* TSDB related object define impelments
*/
#ifndef __TSDB_H__
#define __TSDB_H__

#if defined(USE_ZMALLOC)
#include "zmalloc.h"
#define t_malloc zmalloc
#define t_realloc zrealloc
#define t_free zfree
#else
#define t_malloc malloc
#define t_realloc realloc
#define t_free free
#endif //!USE_ZMALLOC

#include "sds.h"

typedef struct TimeValuePair {
	int64_t timestamp;
	double value;
} tvalue;

static inline void tvalueInit(tvalue* tv) {
	tv->timestamp = 0;
	tv->value = 0;
}

// -------------------------------------------------------------------------
/*
* time series stream
*/
typedef struct timeSeriesStream {
	int64_t 	first_timestamp;
	int64_t		prev_timestamp;
	int64_t		prev_timestamp_delta;

	int64_t		prev_value;
	uint8_t		prev_value_leading_zeros;
	uint8_t		prev_value_trailing_zeros;
	size_t		num_values;
	uint32_t	num_bits;			/* numbers of bits in sds not bytes*/
	sds				data;					/* store ts and value */
} tstream;

/* API */
tstream *tstreamCreate(void);
void tstreamRelease(tstream *t);
void tstreamReset(tstream *t);

/* Size in bytes of the data. */
static inline size_t tstreamSize(tstream *t) {
	if (t && t->data) {
		return sdslen(t->data);
	}

	return 0;
}
/* Allocated size in bytes of the data */
static inline size_t tstreamAlloc(tstream *t) {
	if (t && t->data) {
		return sdsavail(t->data);
	}

	return 0;
}

/* Returns the raw pointer to the stream data. */
static inline sds	tstreamGetData(tstream *t) {
	if (t && t->data) {
		return t->data;
	}

	return 0;
}

void tstreamReadData(tstream *t, sds s);

/*
Returns number of tvalues in this tream O(1)
WARNING: if ts tream read sds data . the number maybe zero but. tsvalue can be read
*/
static inline size_t tstreamNumValues(tstream *t) {
	if (t) return t->num_values;
	return 0;
}

// Appends a time value to the current stream. Returns true if the
// value was successfully added, false otherwise. This function
// might return false if it considers the value to be spam, i.e., it
// was sent too soon after the previous value.
int tstreamAppendtv(tstream *t, tvalue tv, int64_t minTimestampDelta);

// Same as above
int tstreamAppend(tstream *t, int64_t timestamp, double value, int64_t minTimestampDelta);


int64_t tstreamGetFirstTimeStamp(tstream *t);
int64_t tstreamGetPreviousTimeStamp(tstream *t);

/* iterator api */

/* iterator for inspecting tvalue in time series stream */
typedef struct TSIter {
	int64_t		prev_timestamp;
	int64_t		prev_timestamp_delta;

	uint64_t 	prev_value;
  uint8_t 	prev_lead_zeros;
  uint8_t 	prev_trail_zeros;

  uint64_t 	bit_pos;

} tsiter;

void tstreamInitIterator(tsiter *iter);
/* Return 0 has, -1 not has */
int tstreamHasNext(tsiter *iter, tstream *t);
/*Return 0 OK, -1 Error*/
int tstreamNextValue(tsiter *iter, tstream *t, tvalue *tv);


#endif // !__TSDB_H__
